/******
* makecomparable.cpp
*
* Each of these functions takes an abstract stream as an argument
* (ifstream for .txt, stringstream for parsed documents, etc.)
* and returns a vector of derived comparables pulled from that file.
******/

#include "NumberComparable.h"
#include "SpecialComparable.h"
#include "WSComparable.h"
#include "GeneralComparable.h"
#include <cctype>
#include <fstream>
#include <string>
#include <sstream>
#include <vector>
#include <iostream>

template <class T> std::vector<NumberComparable> makeVecNumberComparable(T& aStream)
{
	bool has_decimal = false;
	char c;
	int i = 1;
	int j = 1;
	std::string s = "";
	std::vector<NumberComparable> numVec;

	while (aStream)
	{
		aStream.get(c);

		if (isdigit(c))
		{
			if (s.size() == 0)
				i = j;
			s = s+c;
		}
		
		else if (c == '.')
		{
			if (has_decimal) //numbers only have max of one decimal
			{
				if (s.size() == 1)  //two consecutive decimals - second is the first of new number
					i = j;

				else
				{
					if (s[s.size()-1] == '.')  //if last char is a decimal throw it away
						s[s.size()-1] = 0;
					numVec.push_back(NumberComparable(i,s));
					s = "";
					has_decimal = false;		
				}
			}
				
			else
			{	
				if (s.size() == 0)  //if decimal starts number
					i = j;
				s = s+c;
				has_decimal = true;
			}
		}
	
		else
		{
			if (s.size() > 0)
			{
				if (s[s.size()-1] == '.')  //remove ending decimal, if any
					s[s.size()-1] = 0;
				numVec.push_back(NumberComparable(i,s));
			}
			s = "";
			has_decimal = false;
		}
		
		j++;
	}


	if (s[0] != 0)  //if file ends with a number
		numVec.push_back(NumberComparable(i,s));

	return numVec;
}

template <class T> std::vector<SpecialComparable> makeVecSpecialComparable(T& aStream)
{
	char c;
	int i = 1;
	std::vector<SpecialComparable> specVec;

	while (aStream)
	{
		aStream.get(c);
		if ((!(isalnum(c))) && (c != ' ') && (c != '\t') && (c != '\n'))
			specVec.push_back(SpecialComparable(i,c));
		i++;
	}

	return specVec;
}

template <class T> std::vector<WSComparable> makeVecWSComparable(T& aStream)
{
	char c;
	int i = 1;
	std::vector<WSComparable> WSVec;

	while (aStream)
	{
		aStream.get(c);
		if ((c == ' ') || (c == '\t') || (c == '\n'))
			WSVec.push_back(WSComparable(i,c));
		i++;
	}

	return WSVec;
}

template <class T> std::vector<GeneralComparable> makeVecGeneralComparable(T& aStream)
{
	char c;
	int i = 1;
	std::vector<GeneralComparable> GeneralVec;

	while (aStream)
	{
		aStream.get(c);
		GeneralVec.push_back(GeneralComparable(i,c));
		i++;
	}

	return GeneralVec;
}

